package com.szly.phm.admin.security;


import com.szly.phm.admin.utils.IPUtils;
import com.szly.phm.common.entity.po.SysLog;
import com.szly.phm.common.entity.result.CodeStatusEnum;
import com.szly.phm.common.entity.vo.permissiom.PermissionTreeVO;
import com.szly.phm.common.mapper.SysLogMapper;
import com.szly.phm.common.mapper.SysUserMapper;
import com.szly.phm.common.service.ISysPermissionService;
import com.szly.phm.common.service.ISysRoleService;
import com.szly.phm.common.service.ISysUserService;
import com.szly.phm.common.utils.BeanCopyUtils;
import com.szly.phm.common.utils.HandleUtils;
import com.szly.phm.common.utils.SHA256Utils;
import com.szly.phm.common.utils.TokenUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.Date;
import java.util.concurrent.atomic.AtomicBoolean;

@Component
public class UserLoginHandler implements AuthenticationProvider {
    @Value("${com.jejl.login.universalCode}")
    private String universalCode;
    @Value("${com.jejl.login.enableUniversalPassword}")
    private boolean enableUniversalPassword;

    @Value("${com.jejl.login.universalPassword}")
    private String universalPassword;

    @Autowired
    private ISysUserService userService;

    @Autowired
    private SysUserMapper userMapper;

    @Autowired
    private ISysRoleService roleService;

    @Autowired
    private ISysPermissionService permissionService;
    @Autowired
    private SysLogMapper sysLogMapper;

//
//    @Autowired
//    private LogAsync logAsync;

    @Override
    public UsernamePasswordAuthenticationToken authenticate(Authentication authentication) throws AuthenticationException {
        RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();

        HttpServletRequest request = ((ServletRequestAttributes) requestAttributes).getRequest();
//        var loginLog = new LogLogin();
        var credentials = authentication.getCredentials();
        var password = credentials;
        var username = authentication.getName();
//            loginLog.setId(HandleUtils.UUID32());
        var loginUser = new LoginUser();
        var user = userService.queryUserByUsername(username);
        if (user == null) {
//                loginLog.setLoginState("01");
//                loginLog.setLoginInfo(CodeStatusEnum.UNREGISTERED.getMessage());
//                logAsync.addLoginLog(loginLog);
            throw new BadCredentialsException(CodeStatusEnum.UNREGISTERED.getMessage());
        }
        //万能密码
        if (!(enableUniversalPassword && universalPassword.equals(password))) {
            //密码验证
            var str = new StringBuilder();
            str = str.append(password).append(user.getSalt());
            var pSHA256 = SHA256Utils.SHA256(str.toString());
            if (!user.getPassword().equals(pSHA256)) {
//                    loginLog.setLoginState("01");
//                    loginLog.setLoginInfo(CodeStatusEnum.WRONG_PASSWORD.getMessage());
//                    logAsync.addLoginLog(loginLog);
                throw new BadCredentialsException(CodeStatusEnum.WRONG_PASSWORD.getMessage());
            }

        }
        var log = new SysLog();
        log.setId(HandleUtils.UUID32());
        log.setCreator(user.getUsername());
        log.setCreateDateTime(new Date());
        log.setIpAddress(IPUtils.getRemoteAddr(request));
        log.setRemarks(request.getRequestURI());
        log.setLogType("登录");
        log.setIsSoftDelete(false);
        sysLogMapper.insert(log);
        BeanCopyUtils.copy(user, loginUser);
        loginUser.setPassword(user.getPassword());
        //查询角色
        var roles = roleService.queryRolesByUserId(user.getId());
        loginUser.setRoles(roles);
        //查询权限
        var roleIds = new ArrayList<String>();
        //是否超级管理员
        AtomicBoolean supperAdmin = new AtomicBoolean(false);
        if (HandleUtils.ListIsNotNull(roles)) {
            loginUser.setRoleId(roles.get(0).getId());
            loginUser.setRoleName(roles.get(0).getRoleName());
            roles.forEach(r -> {
                roleIds.add(r.getId());
                if ("超级管理员".equals(r.getRoleName())) {
                    supperAdmin.set(true);
                }
            });
        }
        var permissions = permissionService.queryPermissionsByRoleIds1(roleIds, supperAdmin);
        loginUser.setUserPermissions(permissions);
        //查询系统
//        if (HandleUtils.ListIsNotNull(permissions)) {
//            var wrapper = new LambdaQueryWrapper<SysSystem>();
//            wrapper.eq(SysSystem::getIsSoftDelete, false);
//            wrapper.eq(SysSystem::getId, permissions.get(0).getId());
//            var system = systemService.getOne(wrapper);
//            if (system != null) {
//                loginLog.setSystemId(system.getId());
//                loginUser.setSystemId(system.getId());
//            }
//        }
//        var auths = new StringBuffer();
//        if (HandleUtils.ListIsNotNull(permissions)) {
//            permissions.forEach(m -> {
//                auths.append(m.getRouter()).append(",");
//            });
//            auths.deleteCharAt(auths.length() - 1);
//            loginUser.setAuthorities(AuthorityUtils.commaSeparatedStringToAuthorityList(auths.toString()));
//        }
        // token存入数据库并修改登录次数
        loginUser.setToken(TokenUtils.createTokenExpire(user.getId(), "secretKey"));
        user.setToken(loginUser.getToken());
        userMapper.updateById(user);
        //授权
        var auth = new ArrayList<SimpleGrantedAuthority>();
        if (supperAdmin.get()) {
            //如果是超级管理员
            auth.add(new SimpleGrantedAuthority("supperAdmin"));
        } else {
            for (PermissionTreeVO lp : permissions) {
                auth.add(new SimpleGrantedAuthority(lp.getRouter()));
            }
        }
        loginUser.setUserPermissions(permissions);
//            loginLog.setLoginState("00");
//            loginLog.setLoginInfo(CodeStatusEnum.SUCCESS.getMessage());
//            loginLog.setUserId(user.getId());
//            loginLog.setUserName(user.getUsername());
//            logAsync.addLoginLog(loginLog);
        return new UsernamePasswordAuthenticationToken(loginUser, null, loginUser.getAuthorities());

    }

    @Override
    public boolean supports(Class<?> aClass) {
        return true;
    }


}
